1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 import java.util.regex.*;
32 import sun.misc.FpUtils;
33 import sun.misc.DoubleConsts;
34
35 public class ToHexString {
36 private ToHexString() {}
37
38
39
40
41
42 static String doubleToHexString(double d) {
43 return hexLongStringtoHexDoubleString(Long.toHexString(Double.doubleToLongBits(d)));
44 }
45
46
47
48
49
50 static String hexLongStringtoHexDoubleString(String transString) {
51 transString = transString.toLowerCase();
52
53 String zeros = "";
54 StringBuffer result = new StringBuffer(24);
55
56 for(int i = 0; i < (16 - transString.length()); i++, zeros += "0");
57 transString = zeros + transString;
58
59
60
61 char topChar;
62
63 if((topChar=transString.charAt(0)) >= '8' ) {
64 result.append("-");
65
66 transString =
67 Character.toString(Character.forDigit(Character.digit(topChar, 16) - 8, 16)) +
68 transString.substring(1,16);
69 }
70
71
72 String signifString = transString.substring(3,16);
73
74 if( transString.substring(0,3).equals("7ff") ) {
75 if(signifString.equals("0000000000000")) {
76 result.append("Infinity");
77 }
78 else
79 result.append("NaN");
80 }
81 else {
82
83 int exponent = Integer.parseInt(transString.substring(0,3), 16) -
84 DoubleConsts.EXP_BIAS;
85 result.append("0x");
86
87 if (exponent == DoubleConsts.MIN_EXPONENT - 1) {
88 if(signifString.equals("0000000000000")) {
89 result.append("0.0p0");
90 }
91 else {
92 result.append("0." + signifString.replaceFirst("0+$", "").replaceFirst("^$", "0") +
93 "p-1022");
94 }
95 }
96 else {
97 result.append("1." + signifString.replaceFirst("0+$", "").replaceFirst("^$", "0") +
98 "p" + exponent);
99 }
100 }
101 return result.toString();
102 }
103
104 public static int toHexStringTests() {
105 int failures = 0;
106 String [][] testCases1 = {
107 {"Infinity", "Infinity"},
108 {"-Infinity", "-Infinity"},
109 {"NaN", "NaN"},
110 {"-NaN", "NaN"},
111 {"0.0", "0x0.0p0"},
112 {"-0.0", "-0x0.0p0"},
113 {"1.0", "0x1.0p0"},
114 {"-1.0", "-0x1.0p0"},
115 {"2.0", "0x1.0p1"},
116 {"3.0", "0x1.8p1"},
117 {"0.5", "0x1.0p-1"},
118 {"0.25", "0x1.0p-2"},
119 {"1.7976931348623157e+308", "0x1.fffffffffffffp1023"},
120 {"2.2250738585072014E-308", "0x1.0p-1022"},
121 {"2.225073858507201E-308", "0x0.fffffffffffffp-1022"},
122 {"4.9e-324", "0x0.0000000000001p-1022"}
123 };
124
125
126 for (int i = 0; i < testCases1.length; i++) {
127 String result;
128 if(! (result=Double.toHexString(Double.parseDouble(testCases1[i][0]))).
129 equals(testCases1[i][1])) {
130 failures ++;
131 System.err.println("For floating-point string " + testCases1[i][0] +
132 ", expected hex output " + testCases1[i][1] + ", got " + result +".");
133 }
134 }
135
136
137
138
139
140 String [][] floatTestCases = {
141 {"Infinity", "Infinity"},
142 {"-Infinity", "-Infinity"},
143 {"NaN", "NaN"},
144 {"-NaN", "NaN"},
145 {"0.0", "0x0.0p0"},
146 {"-0.0", "-0x0.0p0"},
147 {"1.0", "0x1.0p0"},
148 {"-1.0", "-0x1.0p0"},
149 {"2.0", "0x1.0p1"},
150 {"3.0", "0x1.8p1"},
151 {"0.5", "0x1.0p-1"},
152 {"0.25", "0x1.0p-2"},
153 {"3.4028235e+38f", "0x1.fffffep127"},
154 {"1.17549435E-38f", "0x1.0p-126"},
155 {"1.1754942E-38", "0x0.fffffep-126"},
156 {"1.4e-45f", "0x0.000002p-126"}
157 };
158
159 for (int i = 0; i < floatTestCases.length; i++) {
160 String result;
161 if(! (result=Float.toHexString(Float.parseFloat(floatTestCases[i][0]))).
162 equals(floatTestCases[i][1])) {
163 failures++;
164 System.err.println("For floating-point string " + floatTestCases[i][0] +
165 ", expected hex output\n" + floatTestCases[i][1] + ", got\n" + result +".");
166 }
167 }
168
169
170
171 String [][] testCases2 = {
172 {"+0.0", "0000000000000000"},
173 {"-0.0", "8000000000000000"},
174 {"+4.9e-324", "0000000000000001"},
175 {"-4.9e-324", "8000000000000001"},
176
177
178 {"+5.00000000000000000000e-01", "3FE0000000000000"},
179 {"-1.66666666666666324348e-01", "BFC5555555555549"},
180 {"+8.33333333332248946124e-03", "3F8111111110F8A6"},
181 {"-1.98412698298579493134e-04", "BF2A01A019C161D5"},
182 {"+2.75573137070700676789e-06", "3EC71DE357B1FE7D"},
183 {"-2.50507602534068634195e-08", "BE5AE5E68A2B9CEB"},
184 {"+1.58969099521155010221e-10", "3DE5D93A5ACFD57C"},
185
186
187 {"+4.16666666666666019037e-02", "3FA555555555554C"},
188 {"-1.38888888888741095749e-03", "BF56C16C16C15177"},
189 {"+2.48015872894767294178e-05", "3EFA01A019CB1590"},
190 {"-2.75573143513906633035e-07", "BE927E4F809C52AD"},
191 {"+2.08757232129817482790e-09", "3E21EE9EBDB4B1C4"},
192 {"-1.13596475577881948265e-11", "BDA8FAE9BE8838D4"},
193
194
195 {"1.67772160000000000000e+07", "4170000000000000"},
196 {"6.36619772367581382433e-01", "3FE45F306DC9C883"},
197 {"1.57079632673412561417e+00", "3FF921FB54400000"},
198 {"6.07710050650619224932e-11", "3DD0B4611A626331"},
199 {"6.07710050630396597660e-11", "3DD0B4611A600000"},
200 {"2.02226624879595063154e-21", "3BA3198A2E037073"},
201 {"2.02226624871116645580e-21", "3BA3198A2E000000"},
202 {"8.47842766036889956997e-32", "397B839A252049C1"},
203
204
205
206 {"+5.42857142857142815906e-01", "3FE15F15F15F15F1"},
207 {"-7.05306122448979611050e-01", "BFE691DE2532C834"},
208 {"+1.41428571428571436819e+00", "3FF6A0EA0EA0EA0F"},
209 {"+1.60714285714285720630e+00", "3FF9B6DB6DB6DB6E"},
210 {"+3.57142857142857150787e-01", "3FD6DB6DB6DB6DB7"},
211 };
212
213
214
215 for (int i = 0; i < testCases2.length; i++) {
216 String result;
217 String expected;
218 if(! (result=Double.toHexString(Double.parseDouble(testCases2[i][0]))).
219 equals( expected=hexLongStringtoHexDoubleString(testCases2[i][1]) )) {
220 failures ++;
221 System.err.println("For floating-point string " + testCases2[i][0] +
222 ", expected hex output " + expected + ", got " + result +".");
223 }
224 }
225
226
227
228 java.util.Random rand = new java.util.Random(0);
229 for (int i = 0; i < 1000; i++) {
230 String result;
231 String expected;
232 double d = rand.nextDouble();
233 if(! (expected=doubleToHexString(d)).equals(result=Double.toHexString(d)) ) {
234 failures ++;
235 System.err.println("For floating-point value " + d +
236 ", expected hex output " + expected + ", got " + result +".");
237 }
238 }
239
240 return failures;
241 }
242
243 public static void main(String argv[]) {
244 int failures = 0;
245
246 failures = toHexStringTests();
247
248 if (failures != 0) {
249 throw new RuntimeException("" + failures + " failures while testing Double.toHexString");
250 }
251 }
252 }